package gnss

import "dgo/goutils/utils"

type RtcmEncoder struct {
	buf []byte
}

func (this *RtcmEncoder) check() {
	if len(this.buf) == 0 {
		this.buf = make([]byte, MAX_RTCM3_RAW_SIZE)
	}
}

func (this *RtcmEncoder) Reset() {
	this.buf = make([]byte, MAX_RTCM3_RAW_SIZE)
}

func (this *RtcmEncoder) RtcmBodyBuf() []byte {
	this.check()
	return this.buf[3:]
}

func (this *RtcmEncoder) EncodeRtcmRawBuf(bodyL int) []byte {
	this.check()
	n := EncodeRtcm3HeadAndCrc(this.buf, 0, bodyL)
	return this.buf[:n]
}

func EncodeBufStr(buf []byte, startBitN *int, str string, max int, lenBitN int) {
	l := len(str)
	if l > max {
		l = max
	}
	SetBitU64(buf, *startBitN, lenBitN, uint64(l))
	*startBitN += lenBitN

	if l > 0 {
		p := *startBitN / 8
		strBuf := []byte(str)
		copy(buf[p:], strBuf[:l])
		*startBitN += l * 8
	}
}

/*
*

	max: 163 Bytes
*/
func EncodeRtcm1033(rec *Gnss1033Rec, buf []byte, startBitN int) (encodedN int) {
	SetBitU16(buf, startBitN, 12, 1033)
	startBitN += 12
	SetBitU16(buf, startBitN, 12, rec.StaId)
	startBitN += 12
	EncodeBufStr(buf, &startBitN, rec.AntennaDescriptor, 31, 8)
	SetBitU8(buf, startBitN, 8, rec.SetupID)
	startBitN += 8
	EncodeBufStr(buf, &startBitN, rec.AntennaSerialNumber, 31, 8)
	EncodeBufStr(buf, &startBitN, rec.ReceiverTypeDescriptor, 31, 8)
	EncodeBufStr(buf, &startBitN, rec.ReceiverFirmwareVersion, 31, 8)
	EncodeBufStr(buf, &startBitN, rec.ReceiverSerialNumber, 31, 8)
	return startBitN
}

func EncodeRtcm1033_ALL(rec *Gnss1033Rec, bb *utils.BytesBuilder, startIdx int) (byteN int) {
	bb.CheckSize(startIdx, 3+163+3) // end crc
	bb.Replace(startIdx, []byte{0xD3, 0, 0})

	byteN = 3
	bitsN := EncodeRtcm1033(rec, bb.Buff(startIdx+3, 163), 0)
	byteN += bitsN / 8
	if bitsN%8 > 0 {
		byteN++
	}

	// 长度
	bb.SetBitU16(startIdx, 8+6, 10, uint16(byteN-3))
	crcBuf := bb.Buff(startIdx, byteN) // 3:同步标记 + 保留位 + 长度（RTCM消息体）(10bit)
	crc1 := utils.CRC24QBuf(crcBuf)
	bb.SetBitU32(startIdx+byteN, 0, 24, uint32(crc1))
	byteN += 3
	bb.Delete2End(startIdx + byteN)
	return
}
